

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.ico">
  <link rel="icon" href="/img/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="Try not to become a man of success but rather try to become a man of value. ">
  <meta name="author" content="kinzun">
  <meta name="keywords" content>
  <meta name="description" content="Docker Cheat Sheet想要一起来完善这份速查表吗？请看贡献手册部分！ 目录 为何使用 Docker 系统环境 安装 容器(Containers) 镜像(Images) 网络(Networks) 仓管中心和仓库(Registry &amp;amp; Repository) Dockerfile 层(Layers) 链接(Links) 卷标(Volumes) 暴露端口(Exposing Port">
<meta name="keywords" content="docker">
<meta property="og:type" content="article">
<meta property="og:title" content="Docker Cheat Sheet">
<meta property="og:url" content="https://kinzun.github.io/2018/05/20/Docker_cheat_sheet/index.html">
<meta property="og:site_name" content="kinzun">
<meta property="og:description" content="Docker Cheat Sheet想要一起来完善这份速查表吗？请看贡献手册部分！ 目录 为何使用 Docker 系统环境 安装 容器(Containers) 镜像(Images) 网络(Networks) 仓管中心和仓库(Registry &amp;amp; Repository) Dockerfile 层(Layers) 链接(Links) 卷标(Volumes) 暴露端口(Exposing Port">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2018-10-04T08:12:40.000Z">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Docker Cheat Sheet">
<meta name="twitter:description" content="Docker Cheat Sheet想要一起来完善这份速查表吗？请看贡献手册部分！ 目录 为何使用 Docker 系统环境 安装 容器(Containers) 镜像(Images) 网络(Networks) 仓管中心和仓库(Registry &amp;amp; Repository) Dockerfile 层(Layers) 链接(Links) 卷标(Volumes) 暴露端口(Exposing Port">
  
  <title>Docker Cheat Sheet - kinzun</title>

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css">


  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4/github-markdown.min.css">
  <link rel="stylesheet" href="/lib/hint/hint.min.css">

  
    
    
      
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10/styles/github-gist.min.css">
    
  

  
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css">
  


<!-- 主题依赖的图标库，不要自行修改 -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">

<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">

<link rel="stylesheet" href="/css/main.css">

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"kinzun.github.io","root":"/","version":"1.8.12","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname"}},"search_path":"/local-search.xml"};
  </script>
  <script src="/js/utils.js"></script>
  <script src="/js/color-schema.js"></script>
</head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>kinzun</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="Docker Cheat Sheet">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2018-05-20 23:40" pubdate>
        2018年5月20日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      12k 字
    </span>
  

  
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      36 分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Docker Cheat Sheet</h1>
            
            <div class="markdown-body">
              <h1 id="Docker-Cheat-Sheet"><a href="#Docker-Cheat-Sheet" class="headerlink" title="Docker Cheat Sheet"></a>Docker Cheat Sheet</h1><p><strong>想要一起来完善这份速查表吗？请看<a href="#贡献手册contributing">贡献手册</a>部分！</strong></p>
<h2 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h2><ul>
<li><a href="#为何使用-docker">为何使用 Docker</a></li>
<li><a href="#系统环境">系统环境</a></li>
<li><a href="#安装">安装</a></li>
<li><a href="#容器container">容器(Containers)</a></li>
<li><a href="#镜像images">镜像(Images)</a></li>
<li><a href="#网络networks">网络(Networks)</a></li>
<li><a href="#仓管中心和仓库registry--repository">仓管中心和仓库(Registry &amp; Repository)</a></li>
<li><a href="#dockerfile">Dockerfile</a></li>
<li><a href="#层layers">层(Layers)</a></li>
<li><a href="#链接links">链接(Links)</a></li>
<li><a href="#卷标volumes">卷标(Volumes)</a></li>
<li><a href="#暴露端口exposing-ports">暴露端口(Exposing Ports)</a></li>
<li><a href="#最佳实践">最佳实践</a></li>
<li><a href="#安全security">安全</a></li>
<li><a href="#小贴士">小贴士</a></li>
<li><a href="#贡献手册contributing">贡献手册(Contributing)</a></li>
</ul>
<h2 id="为何使用-Docker"><a href="#为何使用-Docker" class="headerlink" title="为何使用 Docker"></a>为何使用 Docker</h2><p>“通过 Docker, 开发者可以使用任何语言任何工具创建任何应用。“Dockerized” 的应用是完全可移植的，能在任何地方运行 - 不管是同事的 OS X 和 Windows 笔记本，或是在云端运行的 Ubuntu QA 服务，还是在虚拟机运行的 Red Hat 产品数据中心。</p>
<p> Docker Hub 上有 13,000+ 的应用，开发者可以从中选取一个进行快速扩展开发。Docker 跟踪管理变更和依赖关系，让系统管理员能更容易理解开发人员是如何让应用运转起来的。而开发者可以通过 Docker Hub 的共有/私有仓库，构建他们的自动化编译，与其他合作者共享成果。</p>
<p>Docker 帮助开发者更快地构建和发布高质量的应用。” – <a href="https://www.docker.com/what-docker/#copy1" target="_blank" rel="noopener">什么是 Docker</a></p>
<h2 id="系统环境"><a href="#系统环境" class="headerlink" title="系统环境"></a>系统环境</h2><p>我用的是 <a href="https://github.com/robbyrussell/oh-my-zsh" target="_blank" rel="noopener">Oh My Zsh</a> ，和 <a href="https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker" target="_blank" rel="noopener">Docker 插件</a> ，它可以自动补全 docker 的命令。YMMV。</p>
<h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><p>3.10.x 内核是能运行 Docker 的<a href="https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies" target="_blank" rel="noopener">最低要求</a>。</p>
<h3 id="MacOS"><a href="#MacOS" class="headerlink" title="MacOS"></a>MacOS</h3><p>10.8 “Mountain Lion” 或者更新的版本。</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="Linux-1"><a href="#Linux-1" class="headerlink" title="Linux"></a>Linux</h3><p>Docker 提供了快速安装脚本：</p>
<figure class="highlight vim"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">curl -sSL http<span class="hljs-variable">s:</span>//<span class="hljs-built_in">get</span>.docker.<span class="hljs-keyword">com</span>/ | <span class="hljs-keyword">sh</span><br></code></pre></div></td></tr></table></figure>
<p>如果你不想执行一个不明不白的 shell 脚本，那么请看<a href="https://docs.docker.com/engine/installation/linux/" target="_blank" rel="noopener">安装教程</a>，选择你在用的发行版本。  </p>
<p>如果你是一个 Docker 超新手，那么我建议你先去看看<a href="https://docs.docker.com/engine/getstarted/" target="_blank" rel="noopener">系列教程</a>。</p>
<h3 id="Mac-OS-X"><a href="#Mac-OS-X" class="headerlink" title="Mac OS X"></a>Mac OS X</h3><p>下载和安装 <a href="https://docs.docker.com/toolbox/overview/" target="_blank" rel="noopener">Docker Toolbox</a>。<a href="https://docs.docker.com/docker-for-mac/" target="_blank" rel="noopener">Docker For Mac</a> 很赞，但是它的安装和 VirtualBox 不太一样。详情请查阅<a href="https://docs.docker.com/docker-for-mac/docker-toolbox/" target="_blank" rel="noopener">比较</a>。</p>
<blockquote>
<p><strong>注意</strong> 如果你已经有安装了 docker toolbox，那么你可能会考虑通过 <a href="https://docs.docker.com/machine/install-machine/" target="_blank" rel="noopener">Docker Machine</a> 安装包(不管是从 URL 或是 <code>docker-machine upgrade default</code>)升级，它确实会完成 docker-machine 的升级。但是它不会帮你升级 docker 版本 – <code>docker-machine</code> 变成了 <code>1.10.3</code> 而 <code>docker</code> 还是原来的 <code>1.8.3</code> 或者你之前的什么版本。</p>
<p>所以你最好是通过 Docker Toolbox DMG 文件来升级，它会一次性的帮你处理好所有的升级。</p>
</blockquote>
<p>安装好 Docker Toolbox 之后，通过 VirtualBox provider 安装带 Docker Machine 的 VM:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker-machine create <span class="hljs-attribute">--driver</span>=virtualbox<span class="hljs-built_in"> default<br></span>docker-machine ls<br>eval <span class="hljs-string">"<span class="hljs-variable">$(docker-machine env default)</span>"</span><br></code></pre></div></td></tr></table></figure>
<p>然后启动 container:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-keyword">run</span><span class="bash"> hello-world</span><br></code></pre></div></td></tr></table></figure>
<p>好了，你现在有了一个运行中的 Docker container 了。</p>
<p>如果你是一个 Docker 超新手，那么我建议你先去看看<a href="https://docs.docker.com/engine/getstarted/" target="_blank" rel="noopener">系列教程</a>。</p>
<h2 id="容器-Container"><a href="#容器-Container" class="headerlink" title="容器(Container)"></a>容器(Container)</h2><p><a href="http://etherealmind.com/basics-docker-containers-hypervisors-coreos/" target="_blank" rel="noopener">最基本的 Docker 进程</a>。容器(Container)之于虚拟机(Virtual Machine)就好比线程之于进程。或者你可以把他们想成是 chroots on steroids。</p>
<h3 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/create" target="_blank" rel="noopener"><code>docker create</code></a> 创建一个容器但是不启动。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/rename/" target="_blank" rel="noopener"><code>docker rename</code></a> 允许重命名容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/run" target="_blank" rel="noopener"><code>docker run</code></a> 在同一个操作中创建并启动一个容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/rm" target="_blank" rel="noopener"><code>docker rm</code></a> 删除容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/update/" target="_blank" rel="noopener"><code>docker update</code></a> 更新容器的资源限制。</li>
</ul>
<p>如果你想要一个临时容器，<code>docker run --rm</code> 会在容器停止之后删除它。</p>
<p>如果你想映射宿主(host)的一个文件夹到 docker 容器，<code>docker run -v $HOSTDIR:$DOCKERDIR</code>。参考 <a href="https://github.com/wsargent/docker-cheat-sheet/#volumes" target="_blank" rel="noopener">Volumes</a>。</p>
<p>如果你想同时删除和容器关联的 volumes ，那么在删除容器的时候必须包含 -v 选项，像这样 <code>docker rm -v</code>。</p>
<p>在 docker 1.10 中还有一个 <a href="https://docs.docker.com/engine/admin/logging/overview/" target="_blank" rel="noopener">logging driver</a>，每个容器可以独立使用。如果你想执行 docker 并带上自定义日志驱动，这样 <code>docker run --log-driver=syslog</code></p>
<h3 id="启动和停止"><a href="#启动和停止" class="headerlink" title="启动和停止"></a>启动和停止</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/start" target="_blank" rel="noopener"><code>docker start</code></a> 启动容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/stop" target="_blank" rel="noopener"><code>docker stop</code></a> 停止运行中的容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/restart" target="_blank" rel="noopener"><code>docker restart</code></a> 停止之后再启动容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/pause/" target="_blank" rel="noopener"><code>docker pause</code></a> 暂停运行中的容器，将其 “冻结” 在当前状态。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/unpause/" target="_blank" rel="noopener"><code>docker unpause</code></a> 结束容器暂停状态。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/wait" target="_blank" rel="noopener"><code>docker wait</code></a> 阻塞，到运行中的容器停止为止。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/kill" target="_blank" rel="noopener"><code>docker kill</code></a> 向运行中容器发送 SIGKILL 指令。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/attach" target="_blank" rel="noopener"><code>docker attach</code></a> 链接到运行中容器。</li>
</ul>
<p>如果你想整合容器到<a href="https://docs.docker.com/engine/admin/host_integration/" target="_blank" rel="noopener">宿主进程管理(host process manager)</a>，那么以 <code>-r=false</code> 启动守护进程(daemon)然后使用 <code>docker start -a</code>。</p>
<p>如果你想通过宿主暴露容器的端口(ports)，请看<a href="#exposing-ports">暴露端口</a>一节。</p>
<p>故障 docker 实例的重启策略在<a href="http://container42.com/2014/09/30/docker-restart-policies/" target="_blank" rel="noopener">这里</a>。</p>
<h4 id="CPU-限制"><a href="#CPU-限制" class="headerlink" title="CPU 限制"></a>CPU 限制</h4><p>你可以限制 CPU，包括使用所有 CPU 的百分比，或者使用特定内核数。</p>
<p>比如，你可以设置 <a href="https://docs.docker.com/engine/reference/run/#/cpu-share-constraint" target="_blank" rel="noopener"><code>cpu-shares</code></a> 。这个设置看起来有点奇怪 – 1024 的意思是 100% CPU，因此如果你希望容器使用全体 CPU 内核的 50%，应将其设置为 512。更多信息，请查阅 <a href="https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu" target="_blank" rel="noopener">https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu</a> :</p>
<figure class="highlight applescript"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">run</span> -ti <span class="hljs-comment">--c 512 agileek/cpuset-test</span><br></code></pre></div></td></tr></table></figure>
<p>你可以只对某些 CPU 内核使用 <a href="https://docs.docker.com/engine/reference/run/#/cpuset-constraint" target="_blank" rel="noopener"><code>cpuset-cpus</code></a>]。请参阅 <a href="https://agileek.github.io/docker/2014/08/06/docker-cpuset/" target="_blank" rel="noopener">https://agileek.github.io/docker/2014/08/06/docker-cpuset/</a> 获取更多细节以及一些不错的视频:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-builtin-name">run</span> -ti <span class="hljs-attribute">--cpuset-cpus</span>=0,4,6 agileek/cpuset-test<br></code></pre></div></td></tr></table></figure>
<p>注意，Docker 在容器内仍然可以<strong>看到</strong>所有的 CPU – 虽然它只是用了其中一部分。请查阅 <a href="https://github.com/docker/docker/issues/20770" target="_blank" rel="noopener">https://github.com/docker/docker/issues/20770</a> 获取更多细节。</p>
<h4 id="内存限制"><a href="#内存限制" class="headerlink" title="内存限制"></a>内存限制</h4><p>你同样可以在 Docker 设置<a href="https://docs.docker.com/engine/reference/run/#/user-memory-constraints" target="_blank" rel="noopener">内存限制</a> :</p>
<figure class="highlight applescript"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">run</span> -<span class="hljs-keyword">it</span> -m <span class="hljs-number">300</span>M ubuntu:<span class="hljs-number">14.04</span> /bin/bash<br></code></pre></div></td></tr></table></figure>
<h4 id="能力-Capabilities"><a href="#能力-Capabilities" class="headerlink" title="能力(Capabilities)"></a>能力(Capabilities)</h4><p>Linux 的 capability 可以通过使用 <code>cap-add</code> 和 <code>cap-drop</code> 设置。请参阅 <a href="https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities" target="_blank" rel="noopener">https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities</a> 获取更多细节。这有助于提高安全性。</p>
<p>如需要挂载基于 FUSE 文件系统，你需要同时结合 –cap-add 和 –device 使用:</p>
<figure class="highlight jboss-cli"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker run <span class="hljs-params">--rm</span> -it <span class="hljs-params">--cap-add</span> SYS_ADMIN <span class="hljs-params">--device</span> <span class="hljs-string">/dev/fuse</span> sshfs<br></code></pre></div></td></tr></table></figure>
<p>授予对单个设备访问权限:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-builtin-name">run</span> -it <span class="hljs-attribute">--device</span>=/dev/ttyUSB0 debian bash<br></code></pre></div></td></tr></table></figure>
<p>授予所有设备访问权限:</p>
<figure class="highlight applescript"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">run</span> -<span class="hljs-keyword">it</span> <span class="hljs-comment">--privileged -v /dev/bus/usb:/dev/bus/usb debian bash</span><br></code></pre></div></td></tr></table></figure>
<p>有关容器特权的更多详情请参考<a href="https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities" target="_blank" rel="noopener">这里</a></p>
<h3 id="信息"><a href="#信息" class="headerlink" title="信息"></a>信息</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/ps" target="_blank" rel="noopener"><code>docker ps</code></a> 查看运行中的所有容器。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/logs" target="_blank" rel="noopener"><code>docker logs</code></a> 从容器中获取日志。(你也可以使用自定义日志驱动，不过在 1.10 中，它只支持 <code>json-file</code> 和 <code>journald</code>)</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/inspect" target="_blank" rel="noopener"><code>docker inspect</code></a> 查看某个容器的所有信息(包括 IP 地址)。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/events" target="_blank" rel="noopener"><code>docker events</code></a> 从容器中获取事件(events)。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/port" target="_blank" rel="noopener"><code>docker port</code></a> 查看容器的公开端口。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/top" target="_blank" rel="noopener"><code>docker top</code></a> 查看容器中活动进程。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/stats" target="_blank" rel="noopener"><code>docker stats</code></a> 查看容器的资源使用情况统计信息。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/diff" target="_blank" rel="noopener"><code>docker diff</code></a> 查看容器的 FS 中有变化文件信息。</li>
</ul>
<p><code>docker ps -a</code> 查看所有容器，包括正在运行的和已停止的。</p>
<p><code>docker stats --all</code> 显示正在运行的容器列表 </p>
<h3 id="导入-导出"><a href="#导入-导出" class="headerlink" title="导入 / 导出"></a>导入 / 导出</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/cp" target="_blank" rel="noopener"><code>docker cp</code></a> 在容器和本地文件系统之间复制文件或文件夹。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/export" target="_blank" rel="noopener"><code>docker export</code></a> 将容器的文件系统切换为压缩包(tarball archive stream)输出到 STDOUT。</li>
</ul>
<h3 id="执行命令"><a href="#执行命令" class="headerlink" title="执行命令"></a>执行命令</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/exec" target="_blank" rel="noopener"><code>docker exec</code></a> 在容器中执行命令。</li>
</ul>
<p>比如，进入正在运行的容器，在名为 foo 的容器中打开一个新的 shell 进程: <code>docker exec -it foo /bin/bash</code>.</p>
<h2 id="镜像-Images"><a href="#镜像-Images" class="headerlink" title="镜像(Images)"></a>镜像(Images)</h2><p>镜像是<a href="https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work" target="_blank" rel="noopener">docker 容器的模板</a>。</p>
<h3 id="生命周期-1"><a href="#生命周期-1" class="headerlink" title="生命周期"></a>生命周期</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/images" target="_blank" rel="noopener"><code>docker images</code></a> 查看所有镜像。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/import" target="_blank" rel="noopener"><code>docker import</code></a> 从压缩文件中创建镜像。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/build" target="_blank" rel="noopener"><code>docker build</code></a> 从 Dockerfile 创建镜像。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/commit" target="_blank" rel="noopener"><code>docker commit</code></a> 为容器创建镜像，如果容器正在运行则会临时暂停。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/rmi" target="_blank" rel="noopener"><code>docker rmi</code></a> 删除镜像。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/load" target="_blank" rel="noopener"><code>docker load</code></a> 通过 STDIN 从压缩包加载镜像，包括镜像和标签(images and tags) (0.7 起).</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/save" target="_blank" rel="noopener"><code>docker save</code></a> 通过 STDOUT 保存镜像到压缩包，包括所有的父层，标签和版本(parent layers, tags &amp; versions) (0.7 起).</li>
</ul>
<h3 id="信息-1"><a href="#信息-1" class="headerlink" title="信息"></a>信息</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/history" target="_blank" rel="noopener"><code>docker history</code></a> 查看镜像历史记录。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/tag" target="_blank" rel="noopener"><code>docker tag</code></a> 给镜像命名打标(tags) (本地或者仓库)。</li>
</ul>
<h3 id="清理"><a href="#清理" class="headerlink" title="清理"></a>清理</h3><p>虽然你可以用 <code>docker rmi</code> 命令来删除指定的镜像，但是这里有个称为 <a href="https://github.com/spotify/docker-gc" target="_blank" rel="noopener">docker-gc</a> 的工具，它可以以一种安全的方式，清理掉那些不再被任何容器使用的镜像。</p>
<h3 id="加载-保存镜像"><a href="#加载-保存镜像" class="headerlink" title="加载/保存镜像"></a>加载/保存镜像</h3><p>从文件中加载镜像:<br><figure class="highlight stylus"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker load &lt; my_image<span class="hljs-selector-class">.tar</span><span class="hljs-selector-class">.gz</span><br></code></pre></div></td></tr></table></figure></p>
<p>保存既有镜像:<br><figure class="highlight 1c"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker save my_image:my_tag <span class="hljs-string">| gzip &gt; my_image.tar.gz</span><br></code></pre></div></td></tr></table></figure></p>
<h3 id="导入-导出容器"><a href="#导入-导出容器" class="headerlink" title="导入/导出容器"></a>导入/导出容器</h3><p>从文件中将容器作为镜像导入:<br><figure class="highlight elm"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-title">cat</span> my_container.tar.gz | docker <span class="hljs-keyword">import</span> - my_image:my_tag<br></code></pre></div></td></tr></table></figure></p>
<p>导出既有容器:<br><figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-builtin-name">export</span> my_container | gzip &gt; my_container.tar.gz<br></code></pre></div></td></tr></table></figure></p>
<h3 id="加载被保存的镜像和导入作为镜像导出的容器之间的不同"><a href="#加载被保存的镜像和导入作为镜像导出的容器之间的不同" class="headerlink" title="加载被保存的镜像和导入作为镜像导出的容器之间的不同"></a>加载被保存的镜像和导入作为镜像导出的容器之间的不同</h3><p>通过 <code>load</code> 命令来加载镜像，会创建一个新的镜像，并继承原镜像的所有历史。<br>通过 <code>import</code> 将容器作为镜像导入，也会创建一个新的镜像，但并不包含原镜像的历史，因此生成的镜像会比使用加载方式生成的镜像要小。</p>
<h2 id="网络-Networks"><a href="#网络-Networks" class="headerlink" title="网络(Networks)"></a>网络(Networks)</h2><p>Docker 有<a href="https://docs.docker.com/engine/userguide/networking/" target="_blank" rel="noopener">网络(networks)</a>功能。我并不是很了解它，所以这是一个扩展本文的好地方。这里有篇笔记指出，这是一种可以不使用端口来达成 docker 容器间通信的好方法。详情查阅<a href="https://docs.docker.com/engine/userguide/networking/work-with-networks/" target="_blank" rel="noopener">通过网络来工作</a>。</p>
<h3 id="生命周期-2"><a href="#生命周期-2" class="headerlink" title="生命周期"></a>生命周期</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_create/" target="_blank" rel="noopener"><code>docker network create</code></a></li>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_rm/" target="_blank" rel="noopener"><code>docker network rm</code></a></li>
</ul>
<h3 id="信息-2"><a href="#信息-2" class="headerlink" title="信息"></a>信息</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_ls/" target="_blank" rel="noopener"><code>docker network ls</code></a></li>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_inspect/" target="_blank" rel="noopener"><code>docker network inspect</code></a></li>
</ul>
<h3 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_connect/" target="_blank" rel="noopener"><code>docker network connect</code></a></li>
<li><a href="https://docs.docker.com/engine/reference/commandline/network_disconnect/" target="_blank" rel="noopener"><code>docker network disconnect</code></a></li>
</ul>
<p>你可以为<a href="https://blog.jessfraz.com/post/ips-for-all-the-things/" target="_blank" rel="noopener">容器指定 IP 地址</a>:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-comment"># 使用你自己的子网和网关创建一个桥接网络</span><br>docker<span class="hljs-built_in"> network </span>create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic<br><br><span class="hljs-comment"># 基于以上创建的网络，运行一个nginx容器并指定ip</span><br>$ docker <span class="hljs-builtin-name">run</span> --rm -it --net iptastic --ip 203.0.113.2 nginx<br><br><span class="hljs-comment"># 在其他地方使用curl访问这个ip（假设这是一个公网ip）</span><br>$ curl 203.0.113.2<br></code></pre></div></td></tr></table></figure>
<h2 id="仓管中心和仓库-Registry-amp-Repository"><a href="#仓管中心和仓库-Registry-amp-Repository" class="headerlink" title="仓管中心和仓库(Registry &amp; Repository)"></a>仓管中心和仓库(Registry &amp; Repository)</h2><p>仓库(repository)是<em>被托管(hosted)</em>的已命名镜像(tagged images)集合，这组镜像用于构建容器文件系统。</p>
<p>仓管中心(registry)是一个<em>托管服务(host)</em> – 一个服务，用于存储仓库和提供 HTTP API，以便<a href="https://docs.docker.com/engine/tutorials/dockerrepos/" target="_blank" rel="noopener">管理上传和下载仓库</a>。</p>
<p>Docker.com 把它自己的<a href="https://hub.docker.com/" target="_blank" rel="noopener">索引</a>托管到了它的仓管中心，那里有数量众多的仓库。不过话虽如此，这个仓管中心<a href="https://titanous.com/posts/docker-insecurity" target="_blank" rel="noopener">并没有很好的验证镜像</a>，所以如果你很担心安全问题的话，请尽量避免使用它。</p>
<ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/login" target="_blank" rel="noopener"><code>docker login</code></a> 登入仓管中心。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/logout" target="_blank" rel="noopener"><code>docker logout</code></a> 登出仓管中心。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/search" target="_blank" rel="noopener"><code>docker search</code></a> 从仓管中心检索镜像。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/pull" target="_blank" rel="noopener"><code>docker pull</code></a> 从仓管中心拉去镜像到本地。</li>
<li><a href="https://docs.docker.com/engine/reference/commandline/push" target="_blank" rel="noopener"><code>docker push</code></a> 从本地推送镜像到仓管中心。</li>
</ul>
<h3 id="本地仓管中心"><a href="#本地仓管中心" class="headerlink" title="本地仓管中心"></a>本地仓管中心</h3><p>你可以创立一个本地的仓管中心，通过使用 <a href="https://github.com/docker/distribution" target="_blank" rel="noopener">docker distribution</a> 工程，细节请查看 <a href="https://github.com/docker/docker.github.io/blob/master/registry/deploying.md" target="_blank" rel="noopener">本地发布(local deploy)</a> 介绍。  </p>
<p>也可以参考 <a href="https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution" target="_blank" rel="noopener">邮件列表</a>。</p>
<h2 id="Dockerfile"><a href="#Dockerfile" class="headerlink" title="Dockerfile"></a>Dockerfile</h2><p><a href="https://docs.docker.com/engine/reference/builder/" target="_blank" rel="noopener">配置文件</a>。当你执行 <code>docker build</code> 的时候会根据该配置文件设置 Docker 容器。远优于使用 <code>docker commit</code>。</p>
<p>下面是一些常用的编写 Dockerfile 的编辑器和语法高亮模块︰</p>
<ul>
<li>如果你使用 <a href="http://jedit.org" target="_blank" rel="noopener">jEdit</a>，我为 <a href="https://github.com/wsargent/jedit-docker-mode" target="_blank" rel="noopener">Dockerfile</a> 做了个语法高亮模块。</li>
<li><a href="https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting" target="_blank" rel="noopener">Sublime Text 2</a></li>
<li><a href="https://atom.io/packages/language-docker" target="_blank" rel="noopener">Atom</a></li>
<li><a href="https://github.com/ekalinin/Dockerfile.vim" target="_blank" rel="noopener">Vim</a></li>
<li><a href="https://github.com/spotify/dockerfile-mode" target="_blank" rel="noopener">Emacs</a></li>
<li><a href="https://github.com/docker/docker/tree/master/contrib/syntax/textmate" target="_blank" rel="noopener">TextMate</a></li>
<li>如果要找更全面的关于编辑器或者 IDE 的内容，请看 <a href="https://domeide.github.io/" target="_blank" rel="noopener">当 Docker 遇上 IDE</a></li>
</ul>
<h3 id="指令"><a href="#指令" class="headerlink" title="指令"></a>指令</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file" target="_blank" rel="noopener">.dockerignore</a></li>
<li><a href="https://docs.docker.com/engine/reference/builder/#from" target="_blank" rel="noopener">FROM</a> 为其他指令设置基础镜像(Base Image)。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#maintainer" target="_blank" rel="noopener">MAINTAINER</a> 为生成的镜像设置作者字段。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#run" target="_blank" rel="noopener">RUN</a> 在当前镜像的基础上生成一个新层并执行命令。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#cmd" target="_blank" rel="noopener">CMD</a> 设置容器默认执行命令。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#expose" target="_blank" rel="noopener">EXPOSE</a> 告知 Docker 容器在运行时所要监听的网络端口。注意：并没有实际上将端口设置为可访问。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#env" target="_blank" rel="noopener">ENV</a> 设置环境变量。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#add" target="_blank" rel="noopener">ADD</a> 将文件，文件夹或者远程文件复制到容器中。缓存无效。尽量用 <code>COPY</code> 代替 <code>ADD</code>。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#copy" target="_blank" rel="noopener">COPY</a> 将文件或文件夹复制到容器中。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#entrypoint" target="_blank" rel="noopener">ENTRYPOINT</a> 将一个容器设置为可执行。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#volume" target="_blank" rel="noopener">VOLUME</a> 为外部挂载卷标或其他容器设置挂载点(mount point)。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#user" target="_blank" rel="noopener">USER</a> 设置执行 RUN / CMD / ENTRYPOINT 命令的用户名。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#workdir" target="_blank" rel="noopener">WORKDIR</a> 设置工作目录。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#arg" target="_blank" rel="noopener">ARG</a> 定义编译时(build-time)变量。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#onbuild" target="_blank" rel="noopener">ONBUILD</a> 添加触发指令，当该镜像被作为其他镜像的基础镜像时该指令会被触发。</li>
<li><a href="https://docs.docker.com/engine/reference/builder/#stopsignal" target="_blank" rel="noopener">STOPSIGNAL</a> 设置通过系统向容器发出退出指令。</li>
<li><a href="https://docs.docker.com/engine/userguide/labels-custom-metadata/" target="_blank" rel="noopener">LABEL</a> 将键值对元数据(key/value metadata)应用到你的镜像，容器，或者守护进程。 </li>
</ul>
<h3 id="教程"><a href="#教程" class="headerlink" title="教程"></a>教程</h3><ul>
<li><a href="http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/" target="_blank" rel="noopener">Flux7’s Dockerfile Tutorial</a></li>
</ul>
<h3 id="例子"><a href="#例子" class="headerlink" title="例子"></a>例子</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/builder/#dockerfile-examples" target="_blank" rel="noopener">Examples</a></li>
<li><a href="https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/" target="_blank" rel="noopener">Best practices for writing Dockerfiles</a></li>
<li><a href="http://crosbymichael.com/" target="_blank" rel="noopener">Michael Crosby</a> 还有更多的 <a href="http://crosbymichael.com/dockerfile-best-practices.html" target="_blank" rel="noopener">Dockerfiles best practices</a> / <a href="http://crosbymichael.com/dockerfile-best-practices-take-2.html" target="_blank" rel="noopener">take 2</a></li>
<li><a href="http://jonathan.bergknoff.com/journal/building-good-docker-images" target="_blank" rel="noopener">Building Good Docker Images</a> / <a href="http://jonathan.bergknoff.com/journal/building-better-docker-images" target="_blank" rel="noopener">Building Better Docker Images</a></li>
<li><a href="https://speakerdeck.com/garethr/managing-container-configuration-with-metadata" target="_blank" rel="noopener">Managing Container Configuration with Metadata</a></li>
</ul>
<h2 id="层-Layers"><a href="#层-Layers" class="headerlink" title="层(Layers)"></a>层(Layers)</h2><p>Docker 的版本化文件系统是基于层的。就像<a href="https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/" target="_blank" rel="noopener">git的提交或文件变更系统</a>一样。</p>
<p>注意: 如果你使用 <a href="https://en.wikipedia.org/wiki/Aufs" target="_blank" rel="noopener">aufs</a> 作为你的文件系统，当删除一个容器的时候，Docker 并不一定能成功删除的文件卷标！更多详细信息请参阅 <a href="https://github.com/docker/docker/pull/8484" target="_blank" rel="noopener">PR 8484</a>。</p>
<h2 id="链接-Links"><a href="#链接-Links" class="headerlink" title="链接(Links)"></a>链接(Links)</h2><p>链接(Links)<a href="https://docs.docker.com/userguide/dockerlinks/" target="_blank" rel="noopener">通过 TCP/IP 端口</a>实现了 Docker 容器之间的通讯。<a href="https://docs.docker.com/examples/running_redis_service/" target="_blank" rel="noopener">链接到 Redis</a> 和 <a href="https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/" target="_blank" rel="noopener">Atlassian</a> 是两个可用的例子。你还可以<a href="https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file" target="_blank" rel="noopener">通过 hostname 关联链接</a>。</p>
<p>注意: 如果你希望容器之间<strong>只</strong>通过链接进行通讯，在启动 docker 守护进程的时候请添加参数 <code>-icc=false</code> 来禁用内部进程通讯。</p>
<p>如果你有一个名为 CONTAINER 的容器(通过 <code>docker run --name CONTAINER</code> 指定) 并且在 Dockerfile 中，它的端口暴露为:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">1337</span><br></code></pre></div></td></tr></table></figure>
<p>然后，我们创建另外一个名为 LINKED 的容器:</p>
<figure class="highlight applescript"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">run</span> -d <span class="hljs-comment">--link CONTAINER:ALIAS --name LINKED user/wordpress</span><br></code></pre></div></td></tr></table></figure>
<p>然后 CONTAINER 的端口和别名将会以如下的环境变量出现在 LINKED 中:</p>
<figure class="highlight gams"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-meta"><span class="hljs-meta-keyword">$ALIAS</span>_PORT_1337_TCP_PORT</span><br><span class="hljs-meta"><span class="hljs-meta-keyword">$ALIAS</span>_PORT_1337_TCP_ADDR</span><br></code></pre></div></td></tr></table></figure>
<p>之后你就可以通过这种方式来链接它了。</p>
<p>要删除链接，通过命令 <code>docker rm --link</code>。</p>
<p>通常，docker 服务之间的链接，是”服务发现”的一个子集，如果你打算在生产中大规模使用 Docker，这将是一个很大的问题。请参阅<a href="https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores" target="_blank" rel="noopener">The Docker Ecosystem: Service Discovery and Distributed Configuration Stores</a>获得更多细节。</p>
<h2 id="卷标-Volumes"><a href="#卷标-Volumes" class="headerlink" title="卷标(Volumes)"></a>卷标(Volumes)</h2><p>Docker 的卷标(volumes)是一个<a href="https://docs.docker.com/engine/tutorials/dockervolumes/" target="_blank" rel="noopener">free-floating 文件系统</a>。它们不应该链接到特定的容器上。好的做法是如果可能，应当把卷标挂载到<a href="https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e" target="_blank" rel="noopener">纯数据容器(data-only containers)</a>上。</p>
<h3 id="生命周期-3"><a href="#生命周期-3" class="headerlink" title="生命周期"></a>生命周期</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/volume_create/" target="_blank" rel="noopener"><code>docker volume create</code></a></li>
<li><a href="https://docs.docker.com/engine/reference/commandline/volume_rm/" target="_blank" rel="noopener"><code>docker volume rm</code></a></li>
</ul>
<h3 id="信息-3"><a href="#信息-3" class="headerlink" title="信息"></a>信息</h3><ul>
<li><a href="https://docs.docker.com/engine/reference/commandline/volume_ls/" target="_blank" rel="noopener"><code>docker volume ls</code></a></li>
<li><a href="https://docs.docker.com/engine/reference/commandline/volume_inspect/" target="_blank" rel="noopener"><code>docker volume inspect</code></a></li>
</ul>
<p>卷标在不能使用链接(只有 TCP/IP )的情况下非常有用。例如，如果你有两个 docker 实例需要通讯并在文件系统上留下记录。</p>
<p>你可以一次性将其挂载到多个 docker 容器上，通过 <code>docker run --volumes-from</code>。</p>
<p>因为卷标是独立的文件系统，它们通常被用于存储各容器之间的瞬时状态。也就是说，你可以配置一个无状态临时容器，关掉之后，当你有第二个这种临时容器实例的时候，你可以从上一次保存的状态继续执行。</p>
<p>查看<a href="http://crosbymichael.com/advanced-docker-volumes.html" target="_blank" rel="noopener">卷标进阶</a>来获取更多细节。Container42 <a href="http://container42.com/2014/11/03/docker-indepth-volumes/" target="_blank" rel="noopener">非常有用</a>。</p>
<p>你可以<a href="https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume" target="_blank" rel="noopener">将宿主 MacOS 的文件夹映射为 docker 卷标</a>:</p>
<figure class="highlight groovy"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker run -v <span class="hljs-regexp">/Users/</span>wsargent<span class="hljs-regexp">/myapp/</span><span class="hljs-string">src:</span>/src<br></code></pre></div></td></tr></table></figure>
<p>你也可以用远程 NFS 卷标，如果你觉得你<a href="https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume" target="_blank" rel="noopener">有足够勇气</a>。</p>
<p>可还可以考虑运行一个纯数据容器，像<a href="http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/" target="_blank" rel="noopener">这里</a>所说的那样，提供可移植数据。</p>
<h2 id="暴露端口-Exposing-ports"><a href="#暴露端口-Exposing-ports" class="headerlink" title="暴露端口(Exposing ports)"></a>暴露端口(Exposing ports)</h2><p>通过宿主容器暴露输入端口是相当<a href="https://docs.docker.com/engine/reference/run/#expose-incoming-ports" target="_blank" rel="noopener">繁琐，但有效</a>的。</p>
<p>这种方式可以将容器端口映射到宿主端口上(只使用本地主机(localhost)接口)，通过使用 <code>-p</code>:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-keyword">run</span><span class="bash"> -p 127.0.0.1:<span class="hljs-variable">$HOSTPORT</span>:<span class="hljs-variable">$CONTAINERPORT</span> --name CONTAINER -t someimage</span><br></code></pre></div></td></tr></table></figure>
<p>你可以告诉 Docker 容器在运行时监听指定的网络端口，通过使用 <a href="https://docs.docker.com/engine/reference/builder/#expose" target="_blank" rel="noopener">EXPOSE</a>:</p>
<figure class="highlight xml"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">EXPOSE <span class="hljs-tag">&lt;<span class="hljs-name">CONTAINERPORT</span>&gt;</span><br></code></pre></div></td></tr></table></figure>
<p>但是注意 EXPOSE 并不会暴露端口，你需要用参数 <code>-p</code> 。比如说你要在 localhost 上暴露容器的端口:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">iptables -t<span class="hljs-built_in"> nat </span>-A DOCKER -p tcp --dport &lt;LOCALHOSTPORT&gt; -j DNAT --to-destination &lt;CONTAINERIP&gt;:&lt;PORT&gt;<br></code></pre></div></td></tr></table></figure>
<p>如果你是在 Virtualbox 中运行 Docker，那么你需要转发端口(forward the port)，使用 <a href="https://docs.vagrantup.com/v2/networking/forwarded_ports.html" target="_blank" rel="noopener">forwarded_port</a>。它可以用于在 Vagrantfile 上配置暴露端口段，这样你就可以动态的映射它们了:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">Vagrant.configure(VAGRANTFILE_API_VERSION) <span class="hljs-keyword">do</span> |config|<br>  <span class="hljs-built_in">..</span>.<br><br>  (49000<span class="hljs-built_in">..</span>49900).each <span class="hljs-keyword">do</span> |port|<br>    config.vm.network :forwarded_port, :host =&gt; port, :guest =&gt;<span class="hljs-built_in"> port<br></span>  end<br><br>  <span class="hljs-built_in">..</span>.<br>end<br></code></pre></div></td></tr></table></figure>
<p>如果你忘记你将什么端口映射到宿主容器上的话，使用 <code>docker port</code> 来查看它:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker<span class="hljs-built_in"> port </span>CONTAINER <span class="hljs-variable">$CONTAINERPORT</span><br></code></pre></div></td></tr></table></figure>
<h2 id="最佳实践"><a href="#最佳实践" class="headerlink" title="最佳实践"></a>最佳实践</h2><p>这里有一些最佳实践的总结，以及一些讨论:</p>
<ul>
<li><a href="http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/" target="_blank" rel="noopener">The Rabbit Hole of Using Docker in Automated Tests</a></li>
<li><a href="https://twitter.com/bridgetkromhout" target="_blank" rel="noopener">Bridget Kromhout</a> has a useful blog post on <a href="http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html" target="_blank" rel="noopener">running Docker in production</a> at Dramafever.  </li>
<li>There’s also a best practices <a href="http://developers.lyst.com/devops/2014/12/08/docker/" target="_blank" rel="noopener">blog post</a> from Lyst.</li>
<li><a href="https://engineering.salesforceiq.com/2013/11/05/a-docker-dev-environment-in-24-hours-part-2-of-2.html" target="_blank" rel="noopener">A Docker Dev Environment in 24 Hours!</a></li>
<li><a href="https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/" target="_blank" rel="noopener">Building a Development Environment With Docker</a></li>
<li><a href="https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container" target="_blank" rel="noopener">Discourse in a Docker Container</a></li>
</ul>
<h2 id="安全-Security"><a href="#安全-Security" class="headerlink" title="安全(Security)"></a>安全(Security)</h2><p>这节准备讨论一些关于 Docker 安全性的问题。<a href="https://docs.docker.com/articles/security/" target="_blank" rel="noopener">安全</a>这章讲述了更多细节。</p>
<p>首先第一件事: Docker 是有 root 权限的。如果你在 <code>docker</code> 组，那么你就有<a href="http://reventlov.com/advisories/using-the-docker-command-to-root-the-host" target="_blank" rel="noopener"> root 权限</a>。如果你暴露了 docker unix socket 给容器，意味着你赋予了容器<a href="https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html" target="_blank" rel="noopener">宿主的 root 权限</a>。Docker 不应该是你唯一的防御措施。</p>
<h3 id="安全提示"><a href="#安全提示" class="headerlink" title="安全提示"></a>安全提示</h3><p>为了最大的安全性，你应该会考虑在虚拟机上运行 Docker 。这是直接从 Docker 安全团队拿来的资料 – <a href="http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security" target="_blank" rel="noopener">slides</a> / <a href="http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/" target="_blank" rel="noopener">notes</a>。然后，可以使用 AppArmor / seccomp / SELinux / grsec 之类的来<a href="http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/" target="_blank" rel="noopener">限制容器的权限</a>。更多细节，请查阅 <a href="https://blog.docker.com/2016/02/docker-engine-1-10-security/" target="_blank" rel="noopener">Docker 1.10 security features</a>。</p>
<p>Docker 镜像 id 属于<a href="https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4" target="_blank" rel="noopener">敏感信息</a> 所以它不应该向外界公开。你应该把他们当成密码来对待。</p>
<p>参考 <a href="https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc" target="_blank" rel="noopener">Docker Security Cheat Sheet</a>中 - 作者是 <a href="https://github.com/konstruktoid" target="_blank" rel="noopener">Thomas Sjögren</a> - 关于如何提高容器安全的建议。</p>
<p>下载<a href="https://github.com/docker/docker-bench-security" target="_blank" rel="noopener">docker 安全测试脚本</a>，下载<a href="https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/" target="_blank" rel="noopener">白皮书</a> 以及订阅<a href="https://www.docker.com/docker-security" target="_blank" rel="noopener">邮件列表</a> (不幸的是 Docker 并没有独立的邮件列表，只有 dev / user)。</p>
<p>你应该远离那些使用编译版本 grsecurity / pax 的不稳定内核，比如 <a href="https://en.wikipedia.org/wiki/Alpine_Linux" target="_blank" rel="noopener">Alpine Linux</a>。如果在产品中用了 grsecurity ，那么你应该考虑使用有<a href="https://grsecurity.net/business_support.php" target="_blank" rel="noopener">商业支持</a>的<a href="https://grsecurity.net/announce.php" target="_blank" rel="noopener">稳定版本</a>，就像你对待 RedHat 那样。它要 $200 每月，对于你的运维预算来说不值一提。</p>
<p>从 docker 1.11 开始，你可以轻松的限制在容器中可用的进程数，以防止 fork bombs。 这要求 linux 内核 &gt;= 4.3 并且要在内核配置中打开 CGROUP_PIDS=y 。</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-builtin-name">run</span> <span class="hljs-attribute">--pids-limit</span>=64<br></code></pre></div></td></tr></table></figure>
<p>同时，从 docker 1.11 开始，你也可以限制进程有再获取新权限的能力了。该功能是 linux 内核从 version 3.5 开始就拥有的。你可以从<a href="http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/" target="_blank" rel="noopener">这篇博客</a>中阅读到更多关于这方面的内容。</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-builtin-name">run</span> <span class="hljs-attribute">--security-opt</span>=<span class="hljs-literal">no</span>-new-privileges<br></code></pre></div></td></tr></table></figure>
<p>参考 <a href="http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf" target="_blank" rel="noopener">Docker Security Cheat Sheet</a> (它是个 PDF 版本，搞得非常难用，所以拷贝出来了) 的 <a href="http://container-solutions.com/is-docker-safe-for-production/" target="_blank" rel="noopener">容器解決方案</a>:</p>
<p>关闭内部进程通讯:</p>
<figure class="highlight brainfuck"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-comment">docker</span> <span class="hljs-literal">-</span><span class="hljs-comment">d</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">icc=false</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">iptables</span><br></code></pre></div></td></tr></table></figure>
<p>设置容器为只读:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-keyword">run</span><span class="bash"> --<span class="hljs-built_in">read</span>-only</span><br></code></pre></div></td></tr></table></figure>
<p>通过 hashsum 来验证卷标:</p>
<figure class="highlight elixir"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker pull debian<span class="hljs-variable">@sha256</span><span class="hljs-symbol">:a25306f3850e1bd44541976aa7b5fd0a29be</span><br></code></pre></div></td></tr></table></figure>
<p>设置卷标为只读:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-keyword">run</span><span class="bash"> -v $(<span class="hljs-built_in">pwd</span>)/secrets:/secrets:ro debian</span><br></code></pre></div></td></tr></table></figure>
<p>在 Dockerfile 中定义并运行一个用户，避免在容器中以 root 身份操作:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-builtin-name">RUN</span> groupadd -r<span class="hljs-built_in"> user </span>&amp;&amp; useradd -r -g<span class="hljs-built_in"> user user<br>USER </span>user<br></code></pre></div></td></tr></table></figure>
<h3 id="用户命名空间-User-Namespaces"><a href="#用户命名空间-User-Namespaces" class="headerlink" title="用户命名空间(User Namespaces)"></a>用户命名空间(User Namespaces)</h3><p>还可以通过使用 <a href="https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/" target="_blank" rel="noopener">user namespaces</a> – 这已经是 1.10 内建功能了，但默认情况下是不启用的。</p>
<p>要在 Ubuntu 15.10 中启用用户命名空间 (“remap the userns”)，请<a href="https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/" target="_blank" rel="noopener">跟着这篇博客的例子</a>来做。</p>
<h3 id="安全相关视频"><a href="#安全相关视频" class="headerlink" title="安全相关视频"></a>安全相关视频</h3><ul>
<li><a href="https://youtu.be/04LOuMgNj9U" target="_blank" rel="noopener">Using Docker Safely</a></li>
<li><a href="https://youtu.be/KmxOXmPhZbk" target="_blank" rel="noopener">Securing your applications using Docker</a></li>
<li><a href="https://youtu.be/a9lE9Urr6AQ" target="_blank" rel="noopener">Container security: Do containers actually contain?</a></li>
</ul>
<h3 id="安全路线图"><a href="#安全路线图" class="headerlink" title="安全路线图"></a>安全路线图</h3><p>Docker 的路线图提到关于<a href="https://github.com/docker/docker/blob/master/ROADMAP.md#11-security" target="_blank" rel="noopener">seccomp 的支持</a>。<br>这里有个 AppArmor 策略生成器，叫做 <a href="https://github.com/jfrazelle/bane" target="_blank" rel="noopener">bane</a>，他们正在实现<a href="https://github.com/docker/docker/issues/17142" target="_blank" rel="noopener">安全配置文件</a>。</p>
<h2 id="小贴士"><a href="#小贴士" class="headerlink" title="小贴士"></a>小贴士</h2><p>来源:</p>
<ul>
<li><a href="http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes" target="_blank" rel="noopener">15 Docker Tips in 5 minutes</a></li>
</ul>
<h3 id="最后的-Ids"><a href="#最后的-Ids" class="headerlink" title="最后的 Ids"></a>最后的 Ids</h3><figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">alias dl=<span class="hljs-string">'docker ps -l -q'</span><br>docker <span class="hljs-keyword">run</span><span class="bash"> ubuntu <span class="hljs-built_in">echo</span> hello world<br></span>docker commit `dl` helloworld<br></code></pre></div></td></tr></table></figure>
<h3 id="带命令行的提交-需要-Dockerfile"><a href="#带命令行的提交-需要-Dockerfile" class="headerlink" title="带命令行的提交 (需要 Dockerfile)"></a>带命令行的提交 (需要 Dockerfile)</h3><figure class="highlight autohotkey"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker commit -run='&#123;<span class="hljs-string">"Cmd"</span>:[<span class="hljs-string">"postgres"</span>, <span class="hljs-string">"-too -many -opts"</span>]&#125;' `dl` postgres<br></code></pre></div></td></tr></table></figure>
<h3 id="获取-IP-地址"><a href="#获取-IP-地址" class="headerlink" title="获取 IP 地址"></a>获取 IP 地址</h3><figure class="highlight clean"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker inspect `dl` | grep IPAddress | cut -d <span class="hljs-string">'"'</span> -f <span class="hljs-number">4</span><br></code></pre></div></td></tr></table></figure>
<p>或者安装 <a href="https://stedolan.github.io/jq/" target="_blank" rel="noopener">jq</a>:</p>
<figure class="highlight clean"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker inspect `dl` | jq -r <span class="hljs-string">'.[0].NetworkSettings.IPAddress'</span><br></code></pre></div></td></tr></table></figure>
<p>或者用<a href="https://docs.docker.com/engine/reference/commandline/inspect" target="_blank" rel="noopener">go 模板</a></p>
<figure class="highlight django"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="xml">docker inspect -f '</span><span class="hljs-template-variable">&#123;&#123; .NetworkSettings.IPAddress &#125;&#125;</span><span class="xml">' <span class="hljs-tag">&lt;<span class="hljs-name">container_name</span>&gt;</span></span><br></code></pre></div></td></tr></table></figure>
<h3 id="获取端口映射"><a href="#获取端口映射" class="headerlink" title="获取端口映射"></a>获取端口映射</h3><figure class="highlight nginx"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-attribute">docker</span> inspect -f <span class="hljs-string">'&#123;&#123;range <span class="hljs-variable">$p</span>, <span class="hljs-variable">$conf</span> := .NetworkSettings.Ports&#125;&#125; &#123;&#123;<span class="hljs-variable">$p</span>&#125;&#125; -&gt; &#123;&#123;(index <span class="hljs-variable">$conf</span> 0).HostPort&#125;&#125; &#123;&#123;end&#125;&#125;'</span> &lt;containername&gt;<br></code></pre></div></td></tr></table></figure>
<h3 id="通过正则获取容器"><a href="#通过正则获取容器" class="headerlink" title="通过正则获取容器"></a>通过正则获取容器</h3><figure class="highlight bash"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> $(docker ps -a | grep <span class="hljs-string">"REGEXP_PATTERN"</span> | cut -f1 -d<span class="hljs-string">" "</span>); <span class="hljs-keyword">do</span> <span class="hljs-built_in">echo</span> <span class="hljs-variable">$i</span>; <span class="hljs-keyword">done</span>`<br></code></pre></div></td></tr></table></figure>
<h3 id="获取环境设定"><a href="#获取环境设定" class="headerlink" title="获取环境设定"></a>获取环境设定</h3><figure class="highlight applescript"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">run</span> <span class="hljs-comment">--rm ubuntu env</span><br></code></pre></div></td></tr></table></figure>
<h3 id="强迫关闭正在运行的容器"><a href="#强迫关闭正在运行的容器" class="headerlink" title="强迫关闭正在运行的容器"></a>强迫关闭正在运行的容器</h3><figure class="highlight bash"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-built_in">kill</span> $(docker ps -q)<br></code></pre></div></td></tr></table></figure>
<h3 id="删除旧容器"><a href="#删除旧容器" class="headerlink" title="删除旧容器"></a>删除旧容器</h3><figure class="highlight nginx"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-attribute">docker</span> ps -a | grep <span class="hljs-string">'weeks ago'</span> | awk <span class="hljs-string">'&#123;print <span class="hljs-variable">$1</span>&#125;'</span> | xargs docker rm<br></code></pre></div></td></tr></table></figure>
<h3 id="删除停止容器"><a href="#删除停止容器" class="headerlink" title="删除停止容器"></a>删除停止容器</h3><figure class="highlight stylus"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker rm -v `docker ps -<span class="hljs-selector-tag">a</span> -<span class="hljs-selector-tag">q</span> -f status=exited`<br></code></pre></div></td></tr></table></figure>
<h3 id="删除-dangling-镜像"><a href="#删除-dangling-镜像" class="headerlink" title="删除 dangling 镜像"></a>删除 dangling 镜像</h3><figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker rmi $(docker images -q -f <span class="hljs-attribute">dangling</span>=<span class="hljs-literal">true</span>)<br></code></pre></div></td></tr></table></figure>
<h3 id="删除所有镜像"><a href="#删除所有镜像" class="headerlink" title="删除所有镜像"></a>删除所有镜像</h3><figure class="highlight elixir"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker rmi <span class="hljs-variable">$(</span>docker images -q)<br></code></pre></div></td></tr></table></figure>
<h3 id="删除-dangling-卷标"><a href="#删除-dangling-卷标" class="headerlink" title="删除 dangling 卷标"></a>删除 dangling 卷标</h3><p>Docker 1.9 开始:</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker <span class="hljs-keyword">volume</span><span class="bash"> rm $(docker volume ls -q -f dangling=<span class="hljs-literal">true</span>)</span><br></code></pre></div></td></tr></table></figure>
<p>1.9.0 中，过滤器 <code>dangling=false</code> 居然 _没_ 用 - 它会被忽略然后列出所有的卷标。</p>
<h3 id="查看镜像依赖"><a href="#查看镜像依赖" class="headerlink" title="查看镜像依赖"></a>查看镜像依赖</h3><figure class="highlight 1c"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker images -viz <span class="hljs-string">| dot -Tpng -o docker.png</span><br></code></pre></div></td></tr></table></figure>
<h3 id="Docker-容器瘦身-Intercity-博客"><a href="#Docker-容器瘦身-Intercity-博客" class="headerlink" title="Docker 容器瘦身  Intercity 博客"></a>Docker 容器瘦身  <a href="http://bit.ly/1Wwo61N" target="_blank" rel="noopener">Intercity 博客</a></h3><ul>
<li>在当前运行层(RUN layer)清理 APT</li>
</ul>
<p>这应当和其他 apt 命令在同一层中完成。<br>否则，前面的层将会保持原有信息，而你的镜像则依旧臃肿。</p>
<figure class="highlight crystal"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">RUN &#123;apt commands&#125; \<br>  &amp;&amp; apt-get clean \  <br>  &amp;&amp; rm -rf /var/<span class="hljs-class"><span class="hljs-keyword">lib</span>/<span class="hljs-title">apt</span>/<span class="hljs-title">lists</span>/* /<span class="hljs-title">tmp</span>/* /<span class="hljs-title">var</span>/<span class="hljs-title">tmp</span>/*</span><br></code></pre></div></td></tr></table></figure>
<ul>
<li><p>压缩镜像</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined"><span class="hljs-attribute">ID</span>=$(docker <span class="hljs-builtin-name">run</span> -d image-name /bin/bash)<br>docker <span class="hljs-builtin-name">export</span> <span class="hljs-variable">$ID</span> | docker import – flat-image-name<br></code></pre></div></td></tr></table></figure>
</li>
<li><p>备份</p>
<figure class="highlight arduino"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">ID=$(docker <span class="hljs-built_in">run</span> -d <span class="hljs-built_in">image</span>-name /bin/bash)<br>(docker <span class="hljs-keyword">export</span> $ID | gzip -c &gt; <span class="hljs-built_in">image</span>.tgz)<br>gzip -dc <span class="hljs-built_in">image</span>.tgz | docker <span class="hljs-keyword">import</span> - flat-<span class="hljs-built_in">image</span>-name<br></code></pre></div></td></tr></table></figure>
</li>
</ul>
<h3 id="监视运行中容器的系统资源利用率"><a href="#监视运行中容器的系统资源利用率" class="headerlink" title="监视运行中容器的系统资源利用率"></a>监视运行中容器的系统资源利用率</h3><p>检查某个单独容器的 CPU, 内存, 和 网络 i/o 使用情况，你可以:</p>
<figure class="highlight xml"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker stats <span class="hljs-tag">&lt;<span class="hljs-name">container</span>&gt;</span><br></code></pre></div></td></tr></table></figure>
<p>按 id 列出所有的容器:</p>
<figure class="highlight elixir"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker stats <span class="hljs-variable">$(</span>docker ps -q)<br></code></pre></div></td></tr></table></figure>
<p>按名称列出所有容器:</p>
<figure class="highlight mel"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker stats $(docker ps --<span class="hljs-keyword">format</span> <span class="hljs-string">'&#123;&#123;.Names&#125;&#125;'</span>)<br></code></pre></div></td></tr></table></figure>
<p>按指定镜像名称列出所有容器:</p>
<figure class="highlight routeros"><table><tr><td class="gutter hljs"><div class="hljs code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><div class="hljs code-wrapper"><pre><code class="hljs undefined">docker ps -a -f <span class="hljs-attribute">ancestor</span>=ubuntu<br></code></pre></div></td></tr></table></figure>
<h2 id="贡献手册-Contributing"><a href="#贡献手册-Contributing" class="headerlink" title="贡献手册(Contributing)"></a>贡献手册(Contributing)</h2><p>这是关于如何为这份速查表做贡献的说明。</p>
<h3 id="打开-README-md"><a href="#打开-README-md" class="headerlink" title="打开 README.md"></a>打开 README.md</h3><p>点击 <a href="https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md" target="_blank" rel="noopener">README.md</a> &lt;– 这个链接</p>
<p>via:<a href="https://github.com/wsargent/docker-cheat-sheet" target="_blank" rel="noopener">GITHUB</a></p>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/docker/">docker</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2018/09/12/字符编码（character encoding,fileoperate/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Python编码，文件编码的操作</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2018/04/22/autopep8/">
                        <span class="hidden-mobile">在mac下pycharm配置autopep8</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
              <!-- Comments -->
              <article class="comments" id="comments" lazyload>
                
                  
                
                

              </article>
            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/js/local-search.js" ></script>



  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>


</body>
</html>
